package org.example.java8.future;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import static java.util.stream.Collectors.toList;

//37CompletableFuture常用API的重点详解下
public class CompletableFutureInAction8 {
    public static void main(String[] args) throws InterruptedException {
        //runAfterBoth
        CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " is running");
            return 1;
        }).runAfterBoth(CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + " is running");
            return 2;
        }), () -> System.out.println("done"));

        //applyToEither
        CompletableFuture.supplyAsync(() -> {
            System.out.println("i am future 1");
            timeSleep(1);
            return 1;
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            System.out.println("i am future 2");
            return 2;
        }), v -> v * 10)
                .thenAccept(System.out::println);

        //acceptEither
        CompletableFuture.supplyAsync(() -> {
            System.out.println("i am future 1");
            timeSleep(1);
            return 1;
        }).acceptEither(CompletableFuture.supplyAsync(() -> {
            System.out.println("i am future 2");
            return 2;
        }), System.out::println);

        //runAfterEither
        CompletableFuture.supplyAsync(() -> {
            timeSleep(1);
            System.out.println("i am future runAfterEither 1");
            return 1;
        }).runAfterEither(CompletableFuture.supplyAsync(() -> {
            System.out.println("i am future runAfterEither 2");
            return 2;
        }), () -> System.out.println("runAfterEither done"));


        List<CompletableFuture<Integer>> collect = Arrays.asList(1, 2, 3, 4)
                .stream()
                .map(i -> CompletableFuture.supplyAsync(() -> 1))
                //静态导入Collectors.toList
                .collect(toList());
        //CompletableFuture.allOf(
        CompletableFuture.anyOf(
                collect.toArray(new CompletableFuture[collect.size()]))
                .thenRun(() -> System.out.println("done"));

        Thread.currentThread().join();

    }

    /**
     * sleep the specify seconds
     */
    private static void timeSleep(long time) {
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
